/**
 * OSAmI: Open Source Ambient Intelligence
 * A simple consumer from data sent by Jennic JN5139 sensors.
 * Copyright (C) Lionel Debroux 2010 (as an engineer in the LCIS-INPG-CTSYS team, for a pre-demo in the FR part of the OSAMI project)
 * Contact: osami-general@osami-commons.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA
 */

package org.osami.demo.jn5139.fake;

import fr.imag.adele.homega.impl.unidiscovery.DeviceImpl;
import fr.imag.adele.homega.impl.unidiscovery.DeviceEvent;

import java.util.Dictionary;
import java.util.Enumeration;
import java.util.UUID;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator extends DeviceImpl implements Runnable, BundleActivator {

    /// TODO: make configurable (JMX ? Config Admin ?)
    private String computerAddress = "fd04:0bd3:80e8:0001::2";
    private String localAddress = "fd04:0bd3:80e8:0001::1";
    private String deviceAddress = "FD04:0BD3:80E8:0002:0215:8D00:000F:A1CE";
    /// TODO: make configurable (JMX ? Config Admin ?)
    private int bridgePort = 0xF0B2;
    /// TODO: make configurable (JMX ? Config Admin ?)
    private int dataPort = 0xF0B1;
    private DeviceEvent event;
    /// TODO: make configurable (JMX ? Config Admin ?)
    private int eventInterval = 2000; // in milliseconds, should be higher in production
    /// TODO: make configurable (JMX ? Config Admin ?)
    private int helloInterval = 10000; // in milliseconds, should be higher in production

    private Thread t = null;
    private boolean shouldStop = false;

    private static final int NAP_TIME = 1000; // in milliseconds


    @Override
    public void start(BundleContext bc) throws Exception {
        System.out.println("=== Starting fake JN5139 device ===");
        initialize(deviceAddress, computerAddress, bridgePort, localAddress, dataPort, deviceAddress);
        event = new DeviceEvent(deviceAddress);
        t = new Thread(this);
        t.start();
    }

    @Override
    public void stop(BundleContext bc) throws Exception {
        System.out.println("=== Stopping fake JN5139 device ===");
        if (t != null)
        {
            shouldStop = true;
            while (shouldStop) {
                Thread.yield();
            }
        }
        shutdown();
    }

    @Override
    public void run() {
        System.out.println("=== Starting thread for fake JN5139 device ===");
        int i = 0;
        while (!shouldStop) {
            try {
                Thread.sleep(NAP_TIME);
                if ((i % (int)(helloInterval / NAP_TIME)) == 0) {
                    hello();
                }
                if ((i % (int)(eventInterval / NAP_TIME)) == 0) {
                    event.removeInfo("Temp");
                    event.removeInfo("Hydro");
                    event.removeInfo("Light");
                    event.addInfo("Temp",  new Long(Math.round(27.0 + Math.random()* 8 - Math.random()* 8)).toString());
                    event.addInfo("Hydro", new Long(Math.round(50.0 + Math.random()*30 - Math.random()*30)).toString());
                    event.addInfo("Light", new Long(Math.round(40.0 + Math.random()*20 - Math.random()*20)).toString());
                    sendEvent(event);
                }
                i++;
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("=== Stopping thread for fake JN5139 device ===");
        shouldStop = false;
    }

    @Override
    protected synchronized void receiveEvent(String id, Dictionary<String,String> dict) {
        Enumeration<String> keys = dict.keys();
        System.out.print("{ ");
        while (keys.hasMoreElements()) {
            final String key = keys.nextElement();
            final String value = dict.get(key);
            System.out.print("\"" + key + "\" : " + value + ",");
        }
        System.out.print(" }");
    }
}
